<?php

/*
    picopress - A lightweighed online publishing system
    Copyright (C) 2010  Martin Burkert <martin@burkert.de>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
*/

function get_page_file ($node) {

    $page_file = false;

    if(is_file(MOUNT_DIR.'/'.$node.PAGE_EXTENSION)){
        $page_file = MOUNT_DIR.'/'.$node.PAGE_EXTENSION;
    }else if (is_dir(MOUNT_DIR.'/'.$node) && is_file(MOUNT_DIR.'/'.$node.'/'.INDEX_PAGE.PAGE_EXTENSION)){
        $page_file = MOUNT_DIR.'/'.$node.'/'.INDEX_PAGE.PAGE_EXTENSION;
    }

    return $page_file;
}

function get_link_file ($node) {

    $link_file = false;

    if(is_file(MOUNT_DIR.'/'.$node.LINK_EXTENSION)){
        $link_file = MOUNT_DIR.'/'.$node.LINK_EXTENSION;
    }

    return $link_file;
}

function get_node ($page_file) {

    $node = false;

    // filter leading /
    if(substr($page_file,0,1) == '/')
        $page_file = substr($page_file,1,strlen($page_file));

    if(substr($page_file,-1*(strlen(INDEX_PAGE)+strlen(PAGE_EXTENSION)+1)) == '/'.INDEX_PAGE.PAGE_EXTENSION)
        $node = substr($page_file,0,strlen($page_file)-1*(strlen(INDEX_PAGE)+strlen(PAGE_EXTENSION)+1));
        
    else if(substr($page_file,-1*strlen(PAGE_EXTENSION)) == PAGE_EXTENSION)
        $node = substr($page_file,0,strlen($page_file)-1*strlen(PAGE_EXTENSION));              

    else if(substr($page_file,-1*strlen(LINK_EXTENSION)) == LINK_EXTENSION)
        $node = substr($page_file,0,strlen($page_file)-1*strlen(LINK_EXTENSION));  
    
    return $node;
}


function get_node_from_request () {
    
    $node = '';
    
    if(defined('NICE_URLS') && NICE_URLS == true && !isset($_GET['node'])) {
    
        $req_uri = $_SERVER['REQUEST_URI'];

        $path_pfix = explode('/', BASE_URL);
        for($i=0;$i<3;$i++){
            array_shift($path_pfix);
        }
        $path_pfix = '/'.implode('/', $path_pfix);

        if(substr($req_uri,0,strlen($path_pfix)) == $path_pfix) {
            $node = substr($req_uri,strlen($path_pfix)+1,strlen($req_uri));
        }else{
            die('ERROR: Cannot extraxt node from request. Please check BASE_URL in settings.php.');
        }
        
    }else{
        $node = $_GET['node'];
    }

    $node = str_replace('../','', $node);
    $node = str_replace('./','', $node);
    $node = trim($node, '.');

    return $node;
}


function node_is_page ($node) {

    return (is_file(MOUNT_DIR.'/'.$node.PAGE_EXTENSION));

}

function node_is_list ($node) {

    return (is_file(MOUNT_DIR.'/'.$node.'/'.INDEX_PAGE.PAGE_EXTENSION));

}

function node_is_link ($node) {

    return (is_file(MOUNT_DIR.'/'.$node.LINK_EXTENSION));

}

function is_node ($node) {

    $is_node = false;

    if(is_file(MOUNT_DIR.'/'.$node.PAGE_EXTENSION)){
        return true;
    }else if(is_file(MOUNT_DIR.'/'.$node.LINK_EXTENSION)){
        return true;        
    }else if (is_dir(MOUNT_DIR.'/'.$node) && is_file(MOUNT_DIR.'/'.$node.'/'.INDEX_PAGE.PAGE_EXTENSION)){
        return true;
    }    

}

function get_entry_from_node ($node) {
    return path_pop($node);
}

function get_config ($next_path, $base = '') {

    $config = Array();

    $next_node = '';
    $config_path = MOUNT_DIR.$base.'/'.CONFIG_FILE;

    if(is_file($config_path)){
        require($config_path);
    }

    if ($next_path != '') {
        $base = $base.'/'.path_shift($next_path);
        $deeper_config = get_config($next_path, $base);
        $config = array_merge($config, $deeper_config);
    }
    
    return $config;
    
}

function get_page ($node, &$config) {

    $content = file_get_contents(get_page_file($node));
   
    $page = new Page();
    $page->set_config($config);
    $page->set_content($content);

    $node_title = '';
    if($node != '') $node_title = perform_title_mapping(get_entry_from_node($node), $config);
    else $node_title =  perform_title_mapping($config['root_node_title'], $config);
    
    $title = '';
    if(isset($config['title_prefix'])) $title = $config['title_prefix'];
    $title .= $node_title;
    if(isset($config['title_suffix'])) $title .= $config['title_suffix'];
        
    $page->set_title($title);
    $page->set_node_title($node_title);
    
    return $page;

}


function get_menu_structure ($node, $prediscover_depth, &$config) {

    if (strlen($node) > 0)
        $arr_next_path = explode('/', $node);
    else
        $arr_next_path = array(); // prevent the array from having one empty element
        
    $arr_base_path = array();

    $menu_structure = get_menu_structure_rec($arr_base_path, $arr_next_path, $prediscover_depth, $config);
    
    if(isset($config['root_node']) && $config['root_node'] == true) {
    
        $root_node = array();
        $root_node['type'] = 'page';
        $root_node['node'] = '';
        if($node == '') $root_node['selected'] = 1;
        else  $root_node['selected'] = 0;
        $root_node['title'] = $config['root_node_title'];        
        array_unshift($menu_structure, $root_node);
        
    }

    return $menu_structure;
    

}

function get_menu_structure_rec ($arr_base_path, $arr_next_path, $prediscover_depth) {

    $menu = array();
    $next_path_element = '';
    $next_node = '';

    if (count($arr_next_path) > 0){
        // get $next_path_element and remove it from $next_path.
        $next_path_element = array_shift($arr_next_path);
        $next_node = implode('/', $arr_base_path).'/'.$next_path_element;
    }
           
    // discover the menu items at current base path
    $str_base_path = implode('/', $arr_base_path);
    $menu = get_menu_structure_level($str_base_path, $prediscover_depth, $next_path_element, 
                                     $config);
  
    if ($next_node && node_is_list($next_node)) {

        $menu[$next_path_element]['selected'] = 1;
        $struct = get_menu_structure_rec(array_merge($arr_base_path, array($next_path_element)), 
                                                     $arr_next_path, $prediscover_depth);
                                                     
        // check if substructure has elements. If not, simply treat as single page.
        // In other words: If subdirectory only has index.page, don't reveal as submenu
        if(count($struct) > 0){
            $menu[$next_path_element]['struct'] = $struct;      
        } else {
            $menu[$next_path_element]['type'] = $page;  
        }
        
    } else if ($next_node) {
    
        $menu[$next_path_element]['selected'] = 1;
    
    }
    

    return $menu;

}


function get_menu_structure_level ($path, $discover_depth, $discover_letout = false) {

    $config = get_config($path);
    $menu = Array();

    if(is_dir(MOUNT_DIR.'/'.$path)){
        $d = dir(MOUNT_DIR.'/'.$path);
        while (false !== ($file = $d->read())) {
           if (!filter_menu_file($file)){
                if(substr($file, -1*strlen(PAGE_EXTENSION)) == PAGE_EXTENSION && is_file(MOUNT_DIR.'/'.$path.'/'.$file)){
                                
                    $entry = substr($file, 0, strlen($file)-strlen(PAGE_EXTENSION));


                    $menu[$entry]['type'] = 'page';
                    $menu[$entry]['node'] = get_node($path.'/'.$file);

                    if ($selected_page && $file == $selected_page){
                        $menu[$entry]['selected'] = 1;
                    }else{
                        $menu[$entry]['selected'] = 0;
                    }

                } else if(substr($file, -1*strlen(LINK_EXTENSION)) == LINK_EXTENSION && is_file(MOUNT_DIR.'/'.$path.'/'.$file)){
                                
                    $entry = substr($file, 0, strlen($file)-strlen(LINK_EXTENSION));


                    $menu[$entry]['type'] = 'link';
                    $menu[$entry]['node'] = get_node($path.'/'.$file);
                    $menu[$entry]['selected'] = 0;
                    $menu[$entry]['link'] = file_get_contents(MOUNT_DIR.'/'.$path.'/'.$file);
                    
                    

                }else if(is_dir(MOUNT_DIR.'/'.$path.'/'.$file)){
                
                    $entry = $file;

                    $menu[$entry]['type'] = 'list';
                    $menu[$entry]['node'] = get_node($path.'/'.$file.'/'.INDEX_PAGE.PAGE_EXTENSION);
                    $menu[$entry]['selected'] = 0;
                    
                    if ($discover_depth > 0 && $entry != $discover_letout){
                        $menu[$entry]['struct'] = get_menu_structure_level($path.'/'.$entry, $discover_depth-1);
                    }
                }
                
                $menu[$entry]['title'] = perform_title_mapping($entry, $config);                
                
                                
           }
        }
        $d->close();  
     }

    // Sort keys (node entries) lexicographically
    ksort($menu);

    if (isset($config['menu_order'])){
    
        $menu_order = str_replace(' ','', $config['menu_order']);
        $menu_order = explode(',', $menu_order);
        
        $menu_copy = array();
        
        foreach($menu_order as $order_entry){

            if(isset($menu[$order_entry])){
                $menu_copy[$order_entry] = $menu[$order_entry];
                unset($menu[$order_entry]);
            }
        }
        
        $menu = array_merge($menu_copy, $menu);    
    
    }
    
    
    
    return $menu;
    
}

function path_shift (&$path) {
    $segm_path = explode('/', $path);
    $shifted_element = array_shift($segm_path);
    $path = implode('/', $segm_path);
    return $shifted_element;
}

function path_pop (&$path) {
    $segm_path = explode('/', $path);
    $popped_element = array_pop($segm_path);
    $path = implode('/', $segm_path);
    return $popped_element;
}

function perform_title_mapping ($entry, &$config) {

    $mapping;

    if(!isset($config['mapping']) || $config['mapping'] == "") {
            die ("Error: No mapping defined for node $path.");
    }
    
    $mapping_name = $config['mapping'];
    $mapping_class = $mapping_name.'Mapping';
    $mapping_class_file = 'mappings/'.$mapping_name.'/'.$mapping_class.'.class.php';  
    
    if(is_file($mapping_class_file)){
        require_once($mapping_class_file);
        $mapping = new $mapping_class;
    } else {
        die('Mapping '.$mapping_name.' not found.');
    }
    
    if(isset($config['overwrite:'.$entry])){
        $title = $config['overwrite:'.$entry];
    }else {
        $title = $mapping->map($entry);
    }
    
    return $title;     

}


function filter_menu_file ($file) {

    $filter = false;
    $filtered_files = Array('index.html', CONFIG_FILE, INDEX_PAGE.PAGE_EXTENSION);

    if (substr($file, 0, 1) == '.') $filter = true;
    if (!$filter && in_array($file, $filtered_files)) $filter = true;
        
    return $filter;
}

function get_template (&$config) {


    if(!isset($config['template']) || $config['template'] == "") {
        die ("Error: No template defined.");
    }

    $template_name = $config['template'];
    $template_class = $template_name.'Template';
    $template_class_file = 'templates/'.$template_name.'/'.$template_class.'.class.php';

    if(!is_file($template_class_file)) {
        die ('Error: Template "'.$template_name.'" not found.');
    }

    require_once($template_class_file);
    
    $template = new $template_class();
    $template->set_config($config);
    
    // Assign template variables from configuration. Their keys start with template:
    foreach($config as $key => $value) {
    
        if (preg_match("/^template:(.*)$/", $key, $matches)) {
            $template->assign_var($matches[1], $value);
        } 
    
    }
    
    return $template;
    
}


function display_404 ($node) {

    header("HTTP/1.0 404 Not Found");
    print ('<html><head><title>404 Not Found</tile></head>');
    print ('<h1>Not Found</h1><p>The requested page '.htmlspecialchars($node).' was not found on this server.</p>');  
    print ('<hr /><i>'.VERSION_STRING.'</i></html>');

}




function create_link ($node) {

    $link = '';
    if(defined('NICE_URLS') && defined('BASE_URL') && NICE_URLS == true && BASE_URL != '') {
        $link = BASE_URL.'/'.$node;
    }else if(defined('BASE_URL') && BASE_URL != '') {
        $link = BASE_URL.'/'.CONTROLLER_FILE.'?node='.$node;        
    }else {
        $link = '/'.CONTROLLER_FILE.'?node='.$node;        
    }
    
    return $link;
    
}
function get_base_url(){
    if (defined('BASE_URL'))  
        return BASE_URL;
    else
        return false;
}


function get_parsers (&$config, &$template) {

    if(!isset($config['parsers']) || $config['parsers'] == "") {
        die ("Error: No parsers defined.");
    }
    
    $parsers = explode(',', str_replace(' ','', $config['parsers']));
    $parser_obj = array();
    
    foreach ($parsers as $parser_name) {
    
        $parser_class = $parser_name.'Parser';
        $parser_class_file = 'parsers/'.$parser_name.'/'.$parser_class.'.class.php';
    
        if(!is_file($parser_class_file)) {
            die ('Error: Parser "'.$parser_name.'" not found.');
        }
        
        require_once($parser_class_file);
        $parser = new $parser_class;
        $parser->set_template($template);
        array_push($parser_obj, $parser);
    
    }
    
    return $parser_obj;  

}

function base64_url_encode($input)
{
    return strtr(base64_encode($input), '+/=', '-_,');
}

function base64_url_decode($input)
{
    return base64_decode(strtr($input, '-_,', '+/='));
}


function handle_link($node){

    if($lf = get_link_file($node)){
        Header('Location: '.file_get_contents($lf));

    }
}


?>